package onjava.arrays;

// arrays/ArrayCopying.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Demonstrate Arrays.copy() and Arrays.copyOf()
import java.util.*;
import onjava.*;
import static onjava.ArrayShow.*;

/** Superclass */
class Sup { 
  private int id;

  Sup(int n) {
    id = n;
  }

  @Override
  public String toString() {
    return getClass().getSimpleName() + id;
  }
}

/** Subclass */
class Sub extends Sup { 
  Sub(int n) {
    super(n);
  }
}

/**
 * 
 * 数组复制
 *
 * @author Lucky Yang
 */
public class ArrayCopying {
  public static final int SZ = 15;

  public static void main(String[] args) {
    int[] a1 = new int[SZ];
    Arrays.setAll(a1, new Count.Integer()::get);
    show("a1", a1);
    // [1] 基本的数组复制方法
    int[] a2 = Arrays.copyOf(a1, a1.length); 
    // Prove they are distinct arrays:
    Arrays.fill(a1, 1);
    show("a1", a1);
    show("a2", a2);

    // Create a shorter result:
    // [2] 
    a2 = Arrays.copyOf(a2, a2.length / 2); 
    show("a2", a2);
    // Allocate more space:
    a2 = Arrays.copyOf(a2, a2.length + 5);
    show("a2", a2);

    // Also copies wrapped arrays:
    // [3] 复制子集
    Integer[] a3 = new Integer[SZ]; 
    Arrays.setAll(a3, new Count.Integer()::get);
    Integer[] a4 = Arrays.copyOfRange(a3, 4, 12);
    show("a4", a4);

    Sub[] d = new Sub[SZ / 2];
    Arrays.setAll(d, Sub::new);
    // Produce Sup[] from Sub[]:
    // [4]
    Sup[] b = Arrays.copyOf(d, d.length, Sup[].class); 
    show(b);

    // This "downcast" works fine:
    // [5]
    Sub[] d2 = Arrays.copyOf(b, b.length, Sub[].class); 
    show(d2);

    // Bad "downcast" compiles but throws exception:
    Sup[] b2 = new Sup[SZ / 2];
    Arrays.setAll(b2, Sup::new);
    try {
      // [6]
      Arrays.copyOf(
          b2, b2.length, Sub[].class); 
    } catch (Exception e) {
      System.out.println(e);
    }
  }
}
/*
 * Output:
 * a1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
 * a1: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
 * a2: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
 * a2: [0, 1, 2, 3, 4, 5, 6]
 * a2: [0, 1, 2, 3, 4, 5, 6, 0, 0, 0, 0, 0]
 * a4: [4, 5, 6, 7, 8, 9, 10, 11]
 * [Sub0, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6]
 * [Sub0, Sub1, Sub2, Sub3, Sub4, Sub5, Sub6]
 * java.lang.ArrayStoreException
 */
